const APIError = require('../../rest_api').APIError;
const { ArticleModel, RoleModel } = require('../../db/index');
const { isLogin } = require('../lib'); // 验证登录
/**
 * @add 默认为添加收藏 false为取消收藏
 */
async function articleLikes(ctx, add = true) {
    const body = ctx.request.body;
    const token = ctx.headers.token;
    // 传入参数
    const id = body.article_id;

    // 验证登录
    let login;
    try {
        login = await isLogin(token, true);
    } catch (error) {
        throw new APIError(error.code, error.message);
    }

    // 写入
    try {
        if (add) {
            await ArticleModel.findByIdAndUpdate(id, {
                $addToSet: {
                    likes_user: login.id
                }
            });
            // 返回数据
            ctx.rest({
                message: '收藏成功'
            });
        } else {
            await ArticleModel.findByIdAndUpdate(id, {
                $pull: {
                    likes_user: login.id
                }
            });
            // 返回数据
            ctx.rest({
                message: '取消收藏成功'
            });
        }
    } catch (error) {
        throw new APIError('internal:comment_contentType_error', '文章收藏失败');
    }
}

module.exports = {
    //  添加文章
    'POST /api/v1/article': async (ctx, next) => {
        const body = ctx.request.body;
        // 传入参数
        const content = body.content;
        const title = body.title.trim();
        const type = body.type;
        let tags = body.tags;
        let summary = body.summary || '';

        const token = ctx.headers.token;
        // 验证登录
        let login;
        try {
            login = await isLogin(token, true);
        } catch (error) {
            throw new APIError(error.code, error.message);
        }

        // 验证文章内容与标题不能为空
        if (content.trim().length === 0 || title.length === 0) {
            throw new APIError('internal:article_error', '文章内容和标题不能为空');
        }
        // 验证是否选择了文章板块
        if (!type) {
            throw new APIError('internal:article_type', '请选择文章所属板块');
        }

        if (summary.trimAll().length === 0) {
            summary = content;
        }

        // 验证文章标签
        if (typeof (tags) === 'string') {
            tags = tags.split(',');
        } else if (typeof (tags) === 'object') {
            if (!tags instanceof 'array') {
                throw new APIError('article_tag_error', '文章标签格式不正确');
            }
        } else {
            throw new APIError('article_tag_error', '文章标签格式不正确');
        }
        // 写入
        try {
            const data = await ArticleModel.create({
                summary,
                title,
                type,
                tags,
                content,
                auth: login.id
            });
            // 返回数据
            ctx.rest({
                message: '文章发布成功',
                data: {
                    id: data.id
                }
            });
        } catch (error) {
            console.log(error);
            throw new APIError('internal:article_error', '文章发布失败');
        }
        await next();
    },
    //  修改文章
    'PUT /api/v1/article': async (ctx, next) => {
        const body = ctx.request.body;
        // 传入参数
        const id = body.article_id;
        const content = body.content;
        const title = body.title.trim();
        const type = body.type;
        let tags = body.tags;
        let summary = body.summary || '';

        const token = ctx.headers.token;
        // 获取文章
        let queryData;
        try {
            queryData = await ArticleModel.findById(id);
        } catch (error) {
            throw new APIError('article_error', '文章不存在');
        }
        if (!queryData) {
            throw new APIError('article_error', '文章不存在');
        }

        // 判断是否已被删除
        if (queryData.delete) {
            throw new APIError('internal:article_error', '此文章已被删除，无法修改');
        }
        if (!queryData) {
            throw new APIError('article_error', '文章不存在');
        }

        // 验证登录
        let login;
        try {
            login = await isLogin(token, true, ['超级管理员'], queryData.auth);
        } catch (error) {
            throw new APIError(error.code, error.message);
        }

        // 验证文章内容与标题不能为空
        if (content.trim().length === 0 || title.length === 0) {
            throw new APIError('internal:article_error', '文章内容和标题不能为空');
        }
        // 验证是否选择了文章板块
        if (!type) {
            throw new APIError('internal:article_type', '请选择文章所属板块');
        }
        // 验证文章简介
        if (summary.trimAll().length === 0) {
            summary = content.substring(0, 100);
        }

        // 验证文章标签
        if (typeof (tags) === 'string') {
            tags = tags.split(',');
        } else if (typeof (tags) === 'object') {
            if (!tags instanceof 'array') {
                throw new APIError('article_tag_error', '文章标签格式不正确');
            }
        } else {
            throw new APIError('article_tag_error', '文章标签格式不正确');
        }
        // 开始修改
        try {
            await ArticleModel.findByIdAndUpdate(id, {
                summary,
                title,
                type,
                tags,
                content,
                upDate: new Date()
            });
            // 返回数据
            ctx.rest({
                message: '文章修改成功'
            });
        } catch (error) {
            console.log(error);
            throw new APIError('internal:article_error', '文章发布失败');
        }
        await next();
    },
    //  获取文章列表
    'GET /api/v1/article': async (ctx, next) => {
        let body = ctx.query;
        // 传入参数
        let count = parseFloat(body.count) || 10;
        let page = parseFloat(body.page) - 1 || 0;
        let type = body.type;

        // 查询条件
        let conditions;
        if (type) {
            conditions = {
                type,
                delete: false
            };
        } else {
            conditions = {
                delete: false
            };
        };
        // 显示参数
        let needKey = {
            title: 1,
            auth: 1,
            type: 1,
            tags: 1,
            summary: 1,
            upDate: 1,
            createDate: 1
        };

        try {
            const popAuth = {
                path: 'auth',
                select: '_id cname headImg'
            };
            const popType = {
                path: 'type',
                select: '_id name'
            };

            const dataCount = await ArticleModel.find(conditions, needKey).count();
            const data = await ArticleModel.find(conditions, needKey)
                .sort({ upDate: -1 })
                .populate([popAuth, popType])
                .limit(count)
                .skip(page * count);

            // 返回数据
            ctx.rest({
                data,
                count: dataCount,
                page: page + 1
            });
        } catch (error) {
            throw new APIError('internal:comment_list_error', '获取文章列表失败');
        }

        await next();
    },
    //  获取文章板块列表
    'GET /api/v1/article_type': async (ctx, next) => {
        let body = ctx.query;
        // 传入参数
        let count = parseFloat(body.count) || 10;
        let page = parseFloat(body.page) - 1 || 0;

        // 显示参数
        let needKey = {
            name: 1,
            upDate: 1
        };
        try {
            const dataCount = await RoleModel.find({ article_type: true }, needKey).count();
            const data = await RoleModel.find({ article_type: true }, needKey).limit(count).skip(page * count);

            // 返回数据
            ctx.rest({
                data,
                count: dataCount,
                page: page + 1
            });
        } catch (error) {
            throw new APIError('internal:comment_list_error', '获取角色列表失败');
        }
        await next();
    },
    //  获取文章详情
    'GET /api/v1/article_content': async (ctx, next) => {
        let body = ctx.query;
        const token = ctx.headers.token;

        // 传入参数
        let id = body.article_id;
        if (!id || id.length === 0) {
            throw new APIError('internal:article_error', '请传入文章ID');
        }

        // 显示参数
        let needKey = {
            title: 1,
            auth: 1,
            type: 1,
            tags: 1,
            summary: 1,
            content: 1,
            likes_user: 1,
            islike: 1,
            upDate: 1,
            createDate: 1
        };

        try {
            const popAuth = {
                path: 'auth',
                select: '_id cname headImg'
            };
            const popType = {
                path: 'type',
                select: '_id name'
            };
            // 关注者最多显示10个
            const popLikes = {
                path: 'likes_user',
                select: '_id cname headIm',
                options: { limit: 10 }
            };

            let data = await ArticleModel.findById(id, needKey)
                .populate([popAuth, popType, popLikes]);

            // 是否收藏
            if (token) {
                await isLogin(token, true).then(async res => {
                    const islike = await ArticleModel.findOne({
                        '_id': id,
                        likes_user: res.id
                    });
                    if (islike) {
                        data.islike = true;
                    }
                });
            }

            // 返回数据
            ctx.rest({
                data,
            });
        } catch (error) {
            throw new APIError('internal:comment_list_error', '获取文章列表失败');
        }

        await next();
    },
    //  删除文章
    'DELETE /api/v1/article': async (ctx, next) => {
        const body = ctx.request.body;
        const token = ctx.headers.token;
        const id = body.article_id;

        if (id.length === 0) {
            throw new APIError('internal:comment_contentType_error', '请传入评论ID');
        }
        //  获取文章,与所属板块信息
        const queryData = await ArticleModel.findById(id).populate('type');
        // 判断是否已被删除
        if (queryData.delete) {
            throw new APIError('internal:comment_contentType_error', '此评论已被删除，请勿重复删除');
        }
        // 验证登录
        let login;
        try {
            // 验证是否为评论作者或者管理员,本版块版主
            login = await isLogin(token, true, ['超级管理员', '管理员', queryData.type.name], queryData.auth);
        } catch (error) {
            throw new APIError(error.code, error.message);
        }
        // 当删除者不是本人时，需要传入删除原因，并通知被删除评论用户
        if (!login.isoneself) {

        }
        // 验证通过
        try {
            const data = await ArticleModel.findByIdAndUpdate(id, {
                delete: true,
                upDate: new Date()
            });
            // 返回数据
            ctx.rest({
                message: '删除成功'
            });
        } catch (error) {
            console.log(error);
            throw new APIError('internal:comment_error', '删除失败');
        }
        await next();
    },
    //  收藏文章
    'POST /api/v1/article_likes': async (ctx, next) => {
        await articleLikes(ctx);
        await next();
    },
    //  取消收藏文章
    'DELETE /api/v1/article_likes': async (ctx, next) => {
        await articleLikes(ctx, false);
        await next();
    },
    //  文章加精，置顶
    'POST /api/v1/article_operate': async (ctx, next) => {
        const body = ctx.request.body;
        const token = ctx.headers.token;
        // 传入参数
        const id = body.article_id;
        const type = body.type;

        /**
         * type = 0 加精操作
         * type = 1 置顶操作
         * type = 2 封禁操作
         */
        if (type == 0) {
            // 加精
            //  获取文章,与所属板块信息
            const queryData = await ArticleModel.findById(id).populate('type');

            // 验证登录
            let login;
            try {
                login = await isLogin(token, true, ['超级管理员', '管理员', queryData.type.name]);
            } catch (error) {
                throw new APIError(error.code, error.message);
            }

            try {
                await ArticleModel.findByIdAndUpdate(id, {
                    jingpin: {
                        is: true,
                        upDate: new Date()
                    }
                });
                ctx.rest({
                    message: '加精成功'
                });
            } catch (error) {
                throw new APIError('internal:comment_error', '文章加精失败');
            }
        } else if (type == 1) {
            // 置顶
            // 验证登录
            let login;
            try {
                login = await isLogin(token, true, ['超级管理员', '管理员']);
            } catch (error) {
                throw new APIError(error.code, error.message);
            }

            try {
                await ArticleModel.findByIdAndUpdate(id, {
                    top: {
                        is: true,
                        upDate: new Date()
                    }
                });
                ctx.rest({
                    message: '置顶成功'
                });
            } catch (error) {
                throw new APIError('internal:comment_error', '文章置顶失败');
            }
        } else {
            throw new APIError('internal:article_operate_type_error', '操作类型错误');
        }
        await next();
    },
    //  文章取消加精，取消置顶
    'DELETE /api/v1/article_operate': async (ctx, next) => {
        const body = ctx.request.body;
        const token = ctx.headers.token;
        // 传入参数
        const id = body.article_id;
        const type = body.type;

        /**
         * type = 0 加精操作
         * type = 1 置顶操作
         * type = 2 封禁操作
         */

        if (type == 0) {
            // 取消加精
            //  获取文章,与所属板块信息
            const queryData = await ArticleModel.findById(id).populate('type');

            // 验证登录
            let login;
            try {
                login = await isLogin(token, true, ['超级管理员', '管理员', queryData.type.name]);
            } catch (error) {
                throw new APIError(error.code, error.message);
            }

            try {
                await ArticleModel.findByIdAndUpdate(id, {
                    jingpin: {
                        is: false,
                        upDate: new Date()
                    }
                });
                ctx.rest({
                    message: '取消加精成功'
                });
            } catch (error) {
                throw new APIError('internal:article_jiajing_error', '文章取消加精失败');
            }
        } else if (type == 1) {
            // 取消置顶
            // 验证登录
            let login;
            try {
                login = await isLogin(token, true, ['超级管理员', '管理员']);
            } catch (error) {
                throw new APIError(error.code, error.message);
            }

            try {
                await ArticleModel.findByIdAndUpdate(id, {
                    top: {
                        is: false,
                        upDate: new Date()
                    }
                });
                ctx.rest({
                    message: '取消置顶成功'
                });
            } catch (error) {
                throw new APIError('internal:article_zhiding_error', '文章取消置顶失败');
            }
        } else {
            throw new APIError('internal:article_operate_type_error', '操作类型错误');
        }

        await next();
    }
};
